/**
 * Copyright (C) 2011 the author
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.linguamathematica.oa4j;

import java.util.Set;

import static java.lang.String.format;

import com.linguamathematica.oa4j.Analysis.Decisiveness;
import com.linguamathematica.oa4j.Analysis.OfferingGuidance;
import com.linguamathematica.oa4j.Analysis.RequestingGuidance;
import com.linguamathematica.oa4j.Analysis.Result;
import com.linguamathematica.oa4j.Analysis.Temporality;

/**
 * The Class ActionsAnalysis.
 */
public class ActionsAnalysis
{

	/** The actions. */
	private final Set<Action> actions;

	/**
	 * Instantiates a new actions analysis.
	 * 
	 * @param actions
	 *            the actions
	 */
	public ActionsAnalysis(final Set<Action> actions)
	{
		this.actions = actions;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see java.lang.Object#equals(java.lang.Object)
	 */
	@Override
	public boolean equals(final Object obj)
	{
		if (this == obj)
		{
			return true;
		}

		if (obj == null || getClass() != obj.getClass())
		{
			return false;
		}

		return actions.equals(((ActionsAnalysis) obj).actions);
	}

	/**
	 * Gets the actions.
	 * 
	 * @return the actions
	 */
	public Set<Action> getActions()
	{
		return actions;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see java.lang.Object#hashCode()
	 */
	@Override
	public int hashCode()
	{
		final int prime = 31;
		return prime + actions.hashCode();
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see java.lang.Object#toString()
	 */
	@Override
	public String toString()
	{
		final StringBuilder builder = new StringBuilder(format("Actions Analysis%n%n"));

		for (final Action action : actions)
		{
			builder.append(format("%s%n", action));
		}

		return builder.toString();
	}

	/**
	 * The Class Action.
	 */
	public static class Action
	{

		/** The decisiveness. */
		private final Result<Decisiveness> decisiveness;

		/** The offering guidance. */
		private final Result<OfferingGuidance> offeringGuidance;

		/** The requesting guidance. */
		private final Result<RequestingGuidance> requestingGuidance;

		/** The type. */
		private final Result<String> type;

		/** The temporality. */
		private final Set<Result<Temporality>> temporality;

		/** The topic. */
		private final Result<String> topic;

		/**
		 * Instantiates a new action.
		 * 
		 * @param topic
		 *            the topic
		 * @param decisiveness
		 *            the decisiveness
		 * @param offeringGuidance
		 *            the offering guidance
		 * @param requestingGuidance
		 *            the requesting guidance
		 * @param type
		 *            the type
		 * @param temporality
		 *            the temporality
		 */
		public Action(final Result<String> topic, final Result<Decisiveness> decisiveness,
				final Result<OfferingGuidance> offeringGuidance, final Result<RequestingGuidance> requestingGuidance,
				final Result<String> type, final Set<Result<Temporality>> temporality)
		{
			this.topic = topic;
			this.decisiveness = decisiveness;
			this.offeringGuidance = offeringGuidance;
			this.requestingGuidance = requestingGuidance;
			this.type = type;
			this.temporality = temporality;
		}

		/*
		 * (non-Javadoc)
		 * 
		 * @see java.lang.Object#equals(java.lang.Object)
		 */
		@Override
		public boolean equals(final Object obj)
		{
			if (this == obj)
			{
				return true;
			}

			if (obj == null || getClass() != obj.getClass())
			{
				return false;
			}

			final Action other = (Action) obj;

			return decisiveness.equals(other.decisiveness) && offeringGuidance.equals(other.offeringGuidance)
					&& requestingGuidance.equals(other.requestingGuidance) && temporality.equals(other.temporality)
					&& topic.equals(other.topic) && type.equals(other.type);
		}

		/**
		 * Gets the decisiveness.
		 * 
		 * @return the decisiveness
		 */
		public Result<Decisiveness> getDecisiveness()
		{
			return decisiveness;
		}

		/**
		 * Gets the offering guidance.
		 * 
		 * @return the offering guidance
		 */
		public Result<OfferingGuidance> getOfferingGuidance()
		{
			return offeringGuidance;
		}

		/**
		 * Gets the requesting guidance.
		 * 
		 * @return the requesting guidance
		 */
		public Result<RequestingGuidance> getRequestingGuidance()
		{
			return requestingGuidance;
		}

		/**
		 * Gets the temporality.
		 * 
		 * @return the temporality
		 */
		public Set<Result<Temporality>> getTemporality()
		{
			return temporality;
		}

		/**
		 * Gets the topic.
		 * 
		 * @return the topic
		 */
		public Result<String> getTopic()
		{
			return topic;
		}

		/**
		 * Gets the type.
		 * 
		 * @return the type
		 */
		public Result<String> getType()
		{
			return type;
		}

		/*
		 * (non-Javadoc)
		 * 
		 * @see java.lang.Object#hashCode()
		 */
		@Override
		public int hashCode()
		{
			final int prime = 31;
			int theResult = 1;
			theResult = prime * theResult + decisiveness.hashCode();
			theResult = prime * theResult + offeringGuidance.hashCode();
			theResult = prime * theResult + requestingGuidance.hashCode();
			theResult = prime * theResult + temporality.hashCode();
			theResult = prime * theResult + topic.hashCode();
			return prime * theResult + type.hashCode();
		}

		/*
		 * (non-Javadoc)
		 * 
		 * @see java.lang.Object#toString()
		 */
		@Override
		public String toString()
		{
			return format(
					"Action%n topic %s%n decisiveness %s%n offeringGuidance %s%n requestingGuidance %s%n type %s%n temporality %s",
					topic, decisiveness, offeringGuidance, requestingGuidance, type, temporality);
		}
	}

}
